import React from 'react';
import {View, Button, StyleSheet} from 'react-native';

interface Props {
  children: React.ReactNode;
  skeleton?: React.ReactNode;
}

interface State {
  hasError: boolean;
  error: Error | null;
  isFirstLoad: boolean;
}

export default class ErrorBoundary extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      isFirstLoad: true,
    };
  }

  static getDerivedStateFromError(error: Error) {
    return {hasError: true, error};
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
    console.log('Error caught by ErrorBoundary', error);
    console.log('Component stack', errorInfo.componentStack);
  }

  componentDidMount(): void {
    setTimeout(() => {
      this.setState({isFirstLoad: false});
    }, 2000);
  }

  handleRetry() {
    this.setState({
      hasError: false,
      error: null,
      isFirstLoad: true,
    });
    setTimeout(() => {
      this.setState({isFirstLoad: false});
    }, 500);
  }

  render(): React.ReactNode {
    const {hasError, isFirstLoad} = this.state;
    const {skeleton, children} = this.props;

    if (hasError) {
      return (
        <View style={_styles.errorContainer}>
          <Button title="重新加载" onPress={this.handleRetry} />
        </View>
      );
    }

    if (isFirstLoad && skeleton) {
      return <>{skeleton}</>;
    }

    return <>{children}</>;
  }
}

const _styles = StyleSheet.create({
  errorContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    padding: 16,
  },
  errorText: {
    fontSize: 16,
    color: 'red',
    marginBottom: 12,
  },
});
